#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PyScreenBrain Docker镜像构建脚本

这个脚本用于构建PyScreenBrain项目的Docker镜像，包括检查Docker状态、构建镜像等功能

使用方法：
    python deploy/build_docker_image.py
    构建默认标签的镜像

    python deploy/build_docker_image.py --tag v1.0.0
    构建指定标签的镜像

    python deploy/build_docker_image.py --no-buildkit
    禁用BuildKit构建

参数说明：
    -h, --help            显示帮助信息
    --tag TAG, -t TAG     镜像标签，默认为"latest"
    --no-buildkit         禁用BuildKit构建
    --no-cache            不使用缓存构建
    --pull                总是拉取最新的基础镜像
    --format-name         使用项目名称+年月日+Gitcommit格式命名镜像
"""

import os
import sys
import subprocess
import argparse
import datetime
import re


def check_docker_installed():
    """
    检查Docker是否安装

    Returns:
        bool: Docker已安装返回True，否则返回False
    """
    print("检查Docker是否安装...", end=" ")
    try:
        result = subprocess.run(
            ["docker", "--version"],
            capture_output=True,
            text=True,
            check=True
        )
        print("✅ Docker已安装")
        print(f"   {result.stdout.strip()}")
        return True
    except subprocess.CalledProcessError:
        print("❌ Docker未安装")
        print("   请先安装Docker Desktop")
        print("   📥 下载地址：https://www.docker.com/products/docker-desktop")
        return False
    except FileNotFoundError:
        print("❌ Docker命令未找到")
        print("   请先安装Docker Desktop并确保docker命令已添加到环境变量")
        print("   📥 下载地址：https://www.docker.com/products/docker-desktop")
        return False


def check_docker_running():
    """
    检查Docker是否正在运行

    Returns:
        bool: Docker正在运行返回True，否则返回False
    """
    print("检查Docker是否正在运行...", end=" ")
    try:
        subprocess.run(
            ["docker", "info"],
            capture_output=True,
            text=True,
            check=True
        )
        print("✅ Docker正在运行")
        return True
    except subprocess.CalledProcessError:
        print("❌ Docker未运行")
        print("   请启动Docker Desktop")
        return False


def get_git_commit():
    """
    获取当前Git仓库的最新提交哈希值

    Returns:
        str: Git提交哈希值，如果不是Git仓库则返回空字符串
    """
    try:
        result = subprocess.run(
            ["git", "rev-parse", "--short", "HEAD"],
            capture_output=True,
            text=True,
            check=True
        )
        return result.stdout.strip()
    except (subprocess.CalledProcessError, FileNotFoundError):
        return ""


def get_formatted_image_name(project_name="pyscreenbrain"):
    """
    按照项目名称+年月日+Gitcommit格式生成镜像名称

    Args:
        project_name: 项目名称，默认为"pyscreenbrain"

    Returns:
        str: 格式化的镜像名称
    """
    # 获取当前日期时间
    now = datetime.datetime.now()
    date_str = now.strftime("%Y%m%d")
    
    # 获取Git提交哈希
    git_commit = get_git_commit()
    
    # 生成镜像名称
    if git_commit:
        return f"{project_name}:{date_str}-{git_commit}"
    else:
        return f"{project_name}:{date_str}"


def build_docker_image(tag="latest", use_buildkit=True, no_cache=False, pull=False, format_name=False):
    """
    构建Docker镜像

    Args:
        tag: 镜像标签，默认为"latest"
        use_buildkit: 是否使用BuildKit构建，默认为True
        no_cache: 是否不使用缓存构建，默认为False
        pull: 是否总是拉取最新的基础镜像，默认为False
        format_name: 是否使用项目名称+年月日+Gitcommit格式命名镜像，默认为False

    Returns:
        bool: 构建成功返回True，否则返回False
    """
    print("开始构建Docker镜像...")
    
    # 设置镜像名称
    if format_name:
        image_name = get_formatted_image_name()
    else:
        image_name = f"pyscreenbrain:{tag}"
    
    # 设置构建参数
    build_args = []
    
    # 设置环境变量
    env = os.environ.copy()
    if use_buildkit:
        env["DOCKER_BUILDKIT"] = "1"
        print("🔧 使用BuildKit构建")
    else:
        env["DOCKER_BUILDKIT"] = "0"
        print("🔧 不使用BuildKit构建")
    
    if no_cache:
        build_args.append("--no-cache")
        print("🔧 不使用缓存构建")
    
    if pull:
        build_args.append("--pull")
        print("🔧 拉取最新基础镜像")
    
    # 构建命令
    build_cmd = [
        "docker", "build",
        "-t", image_name,
        "-f", "deploy/Dockerfile",
        *build_args,
        "."
    ]
    
    print(f"📋 构建命令：{' '.join(build_cmd)}")
    print(f"📦 镜像名称：{image_name}")
    print("=" * 60)
    
    try:
        # 执行构建命令
        result = subprocess.run(
            build_cmd,
            env=env,
            capture_output=False,
            text=True,
            check=True
        )
        print("=" * 60)
        print(f"🎉 Docker镜像构建成功：{image_name}")
        return True, image_name
    except subprocess.CalledProcessError as e:
        print("=" * 60)
        print(f"❌ Docker镜像构建失败")
        return False, image_name


def show_build_result(success, image_name):
    """
    显示构建结果

    Args:
        success: 构建是否成功
        image_name: 镜像名称
    """
    print("\n" + "=" * 60)
    if success:
        print(f"🎉 Docker镜像构建成功！")
        print(f"📦 镜像名称：{image_name}")
        print("\n💡 运行镜像命令：")
        print(f"   docker run -d -p 5000:5000 -p 5228:5228 -p 8931-8933:8931-8933 {image_name}")
    else:
        print(f"❌ Docker镜像构建失败！")
        print(f"📋 请检查以上错误信息并修复后重试")
    print("=" * 60)


def main():
    """
    主函数
    """
    # 解析命令行参数
    parser = argparse.ArgumentParser(description="PyScreenBrain Docker镜像构建脚本")
    parser.add_argument(
        "--tag", "-t", 
        type=str, 
        default="latest", 
        help="镜像标签，默认为\"latest\""
    )
    parser.add_argument(
        "--no-buildkit", 
        action="store_true", 
        help="禁用BuildKit构建"
    )
    parser.add_argument(
        "--no-cache", 
        action="store_true", 
        help="不使用缓存构建"
    )
    parser.add_argument(
        "--pull", 
        action="store_true", 
        help="总是拉取最新的基础镜像"
    )
    parser.add_argument(
        "--format-name", 
        action="store_true", 
        help="使用项目名称+年月日+Gitcommit格式命名镜像"
    )
    
    args = parser.parse_args()
    
    print("\n🔥 PyScreenBrain Docker镜像构建脚本")
    print("=" * 60)
    
    # 检查Docker状态
    if not check_docker_installed():
        sys.exit(1)
    
    if not check_docker_running():
        sys.exit(1)
    
    # 构建镜像
    success, image_name = build_docker_image(
        tag=args.tag,
        use_buildkit=not args.no_buildkit,
        no_cache=args.no_cache,
        pull=args.pull,
        format_name=args.format_name
    )
    
    # 显示构建结果
    show_build_result(success, image_name)
    
    # 退出程序
    sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()